/***************************************************************
 *  Copyright (c) 2007 by GroupMe! Team (www.groupme.net)
 *  All rights reserved.
 *
 *  This file is part of the GroupMe! Project. Source code of 
 *  this project is closed and redistribution of this code is
 *  prohibited. 
 *  
 *  Contact: http://www.groupme.net
 *
 *  This copyright notice MUST APPEAR in all copies of the file!
 ***************************************************************/

package net.groupme.search.google;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import net.groupme.controller.model.SearchResult;
import net.groupme.exceptions.search.SearchEngineException;
import net.groupme.model.MODEL_CONSTANTS;
import net.groupme.search.manualadd.ManualAddOfRessources;

import com.google.soap.search.GoogleSearch;
import com.google.soap.search.GoogleSearchFault;
import com.google.soap.search.GoogleSearchResult;
import com.google.soap.search.GoogleSearchResultElement;

/**
 * 
 * created on 28.06.2007
 * 
 * This class/interface...
 * 
 * @author Patrick Siehndel <a
 *         href="mailto:patrick.siehndel@gmx.de">patrick.siehndel@gmx.de</a>
 * @author last edited by: $Author: mischa $
 * 
 * @version $Revision: 1.9 $ $Date: 2009-01-13 14:10:34 $
 */

public class GoogleSearchEngine {
	
	/** Logger for this class and subclasses */
	protected final Log logger = LogFactory.getLog(getClass());
	/**
	 * Returns an Array of {@link SearchResult} instances that suit the given
	 * query which are from the Google Search API
	 * 
	 * @param queryKeyword
	 *            The Keyword which is searched for
	 * @param fileType
	 *            Only results of this Filetype are searched for
	 * @param numberOfResults
	 *            The Number of Results which are returned
	 * @return
	 */
	public List<SearchResult> searchGoogle(String queryKeyword,
			String fileType, int numberOfResults) {
		
		GoogleSearch googleSearch = new GoogleSearch();
		googleSearch.setKey(Google_Vocabulary.Google_API_KEY);

		// googleSearch.setQueryString("filetype:"+ fileType + " " +
		// queryKeyword);
		googleSearch.setQueryString(queryKeyword);
		googleSearch.setMaxResults(numberOfResults);
		GoogleSearchResult googleResult = new GoogleSearchResult();

		List<SearchResult> resultList = new ArrayList<SearchResult>();

		int counter = 0;
		try {
			//ManualAddOfRessources manuAdd = new ManualAddOfRessources();
			googleResult = googleSearch.doSearch();
			GoogleSearchResultElement[] liste = googleResult
					.getResultElements();
			while (counter < (liste.length)) {
				
				
				SearchResult result = new SearchResult();
				result.setUrl(liste[counter].getURL());
				result.setType(MODEL_CONSTANTS.RESOURCE_TYPE_WEBSITE);
				result.setDescription(cleanString(liste[counter].getTitle()));
				result.setName( cleanString(liste[counter].getTitle()));
				result.setResultID("googleresult" + counter);
				resultList.add(result);
				
				//List<SearchResult> manuResult = manuAdd.addResourceManual(liste[counter].getURL(), cleanString(liste[counter].getTitle()),  cleanString(liste[counter].getTitle()));
				
				
//				Iterator it = manuResult.iterator();
//				if (it.hasNext()){
//					SearchResult result = (SearchResult) it.next();
//					result.setResultID("googleresult" + counter);
//					resultList.add(result);
//				}
				counter++;
			}
			return resultList;
		} catch (GoogleSearchFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			//Workaround: If the Exception contains the message seen below a new search request is send to google with a modified query keyword (with 'allintitle' at the front)
			//Workaround from googlegroups google.public.web-apis
			if(e.getMessage().contains("Exception from service object: For input string:")){
				logger.error("The Google Search Engine had a problem. Request will be send again with a modified query keyword.");
				String newQueryKeyword = "allintitle:" + queryKeyword;
				return searchGoogle(newQueryKeyword, fileType, numberOfResults);
			}else
				return null;
		}

	}

	/** cleans the <b> and </b> out of the string */
	private String cleanString(String stri) {
		String ret = "";
		ret = stri.replaceAll("<b>", "");
		stri = ret.replaceAll("</b>", "");
		return stri;
	}
}
